using System;
using System.Collections.Generic;
using System.IO;

namespace pal.SvnConf.Core
{
    //Understands the access permissions of an ISecurityPrincipal over a resource identified by a path
    public class Acl
    {
        private const char SECTION_NAME_PREFIX = '[';
        private const char SECTION_NAME_SUFFIX = ']';
        private const char SPACE = ' ';

        private string _resourceName;
        private List<AuthorizationEntry> _authorizationEntries;

        public Acl(string resourceName, List<AuthorizationEntry> authorizationEntries)
        {
            _resourceName = resourceName;
            _authorizationEntries = authorizationEntries;
        }

        public string Name
        {
            get { return _resourceName; }
        }

        public List<AuthorizationEntry> AuthorizationEntries
        {
            get { return _authorizationEntries; }
        }

        public static Acl Parse(string aclSection)
        {
            StringReader reader = new StringReader(aclSection);
            string aclName = String.Empty;
            List<AuthorizationEntry> authorizationEntries = new List<AuthorizationEntry>();
            do
            {
                string line = reader.ReadLine();
                if (isSectionStart(line))
                    aclName = sectionName(line);
                else if (!string.IsNullOrEmpty(line.Trim()))
                    authorizationEntries.Add(AuthorizationEntry.Parse(line));
            } while (streamHasMoreEntries(reader));
            return new Acl(aclName, authorizationEntries);
        }

        private static string sectionName(string line)
        {
            return line.Trim(SECTION_NAME_PREFIX, SECTION_NAME_SUFFIX, SPACE);
        }

        private static bool isSectionStart(string line)
        {
            return line.StartsWith(SECTION_NAME_PREFIX.ToString());
        }

        private static bool streamHasMoreEntries(TextReader textReader)
        {
            return textReader.Peek() != -1;
        }


        public override string ToString()
        {
            return _resourceName;
        }

        public override bool Equals(object other)
        {
            if (other == null || !(other is Acl)) return false;
            if (ReferenceEquals(this, other)) return true;
            if (_resourceName.Equals(((Acl) (other))._resourceName)
                && authorizationEntriesMatch((Acl) other)) return true;
            return false;
        }

        private bool authorizationEntriesMatch(Acl other)
        {
            if (other._authorizationEntries.Count != _authorizationEntries.Count) return false;

            for (int i = 0; i < _authorizationEntries.Count; i++)
            {
                if (!other._authorizationEntries[i].Equals(_authorizationEntries[i]))
                    return false;
            }
            return true;
        }
    }
}